<?php
/**
 * Created by PhpStorm.
 * User: moquan
 * Date: 2018/7/8
 * Time: 18:24
 */

namespace app\common\model;


use app\lib\exception\TokenException;
use think\Cache;
use think\console\command\make\Model;
use think\Exception;
use think\exception\HttpException;
use think\Log;

class WeChatModel extends Model {

    protected $appID;

    protected $appSecret;

    protected $accessToken;

//    public $wxApp;


    public function __construct() {
        parent::__construct();

        $this->appID = config( 'wx.appId' );
        $this->appSecret = config( 'wx.appSecret' );
        $this->accessToken = $this->getAccessToken();
    }

    public function getWxApp(){

    }

    public function oauth(){

        if( !isset($_GET['code']) && !isset($_SESSION['code']) ){
            $this->getCode();
        }else{
            session('code',$_GET['code']);
        }

        if(isset($_GET['code']) && !isset($_SESSION['token'])){
            $this->getAToken($_SESSION['code']);
        }

        if(isset($_SESSION['token'])){
            return $this->getUserInfo($_SESSION['token']);
        }

        return false;

    }

    public function getCode(){
        $url = "http://wenlongli.com/?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=STATE";
        $url = sprintf($url, $this->appID, "http://wenlongli.com" );
        header("Location:".$url);
    }

    public function getAToken( $code ){
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->appID}&secret={$this->appSecret}&code={$code}&grant_type=authorization_code";
        $res = curl_get($url);
        session('token',$res);
        return $res;
    }

    public function getUserInfo( $at ){
        $url = "https://api.weixin.qq.com/sns/userinfo?access_token={$at->access_token}&openid={$at->openid}&lang=zh_CN";
        $res = curl_get($url);
        session('ac',$res);
        return $res;
    }

    public function makeMenu( $data = array() ){
        $data = [
            'button'=>[
                [
                    "type"=>"view",
                    "name"=>"商城",
                    "url"=>"http://myshop.wenlongli.com/"
                ],
                [
                    "type"=>"view",
                    "name"=>"供应商",
                    "url"=>"http://www.soso.com/"
                ]
                /*[
                    "name" => "菜单",
                    "sub_button" => [
                        [
                            "type"=>"view",
                            "name"=>"搜索",
                            "url"=>"http://www.soso.com/"
                        ]
                    ]
                ],
                [
                    "type"=> "scancode_push",
                    "name"=> "扫码推事件",
                    "key"=> "rselfmenu_0_1",
                    "sub_button"=> [ ]
                ],*/
            ]
        ];
        $url = config('wx.create_menu');
        $url = sprintf($url, $this->accessToken );
        $res = json_decode( curl_post( $url, $data ), true );
        if ( $res['errmsg'] != 'ok' ) {
            $err = json_encode( $res, JSON_UNESCAPED_UNICODE );
            $this->recordErrorLog( $err );
            throw new Exception( 'Request WeChat Menu fail. response: '.$err );
        }
        return $res;
    }

    public function responseMsg()
    {
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

        if (!empty($postStr)){
//            libxml_disable_entity_loader(true);
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            if($postObj->MsgType=='event'){
                if($postObj->Event == 'CLICK'){
                    if($postObj->EventKey == 'V1001_TODAY_MUSIC'){
                        echo $this->tpl( $postObj,"微信连,www.phpos.net");
                    }
                }
                if( $postObj->Event='scancode_waitmsg'){
                    echo $this->tpl( $postObj, $postObj->ScanCodeInfo->ScanResult );
                }
            }
        }
    }

    public function tpl( $object, $content, $funcFlag = 0 ){
        $textTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[text]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                        <FuncFlag>%d</FuncFlag>
                    </xml>";
        $resultStr = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content, $funcFlag);
        return $resultStr;
    }

    /*
     * 获取accessToken
     * */
    public function getAccessToken( $refresh = false ){
       //从缓存里取
        $cached = cache('access_token');
        //是否强制刷新
        //缓存不存在
        if ($refresh || empty( $cached )) {
            //获取accessToken
            $token = $this->getAccessTokenFromServer();
            //存入缓存
            Cache::set( 'access_token', $token['access_token'], $token['expires_in'] - 1500 );
            return $token['access_token'];
        }
        return $cached;
    }

    /**
     * 取accessToken
     */
    public function getAccessTokenFromServer()
    {
         $url = config('wx.access_token_url');
         $url = sprintf($url, $this->appID, $this->appSecret );
         $token = json_decode( curl_get( $url ), true );
         if (empty($token['access_token'])) {
             $err = json_encode( $token, JSON_UNESCAPED_UNICODE );
             $this->recordErrorLog( $err );
             throw new Exception( 'Request AccessToken fail. response: '.$err );
         }
        return $token;

    }

    private function recordErrorLog( $data )
    {
        Log::init([
            'type' => 'File',
            'path' => LOG_PATH,
            'level' => ['error']
        ]);
        Log::record( $data, 'error' );
    }


}